Skip to content

feat(engine): anonymize-on-export#48

Merged
sepehr-safari merged 1 commit into
mainfrom
feat/anonymize
Jul 11, 2026
Merged

feat(engine): anonymize-on-export#48
sepehr-safari merged 1 commit into
mainfrom
feat/anonymize

Conversation

@sepehr-safari

Copy link
Copy Markdown
Member

What

feat(engine): trace anonymization (S4 #42) — strip sensitive fields so a
trace can be shared safely.

Closes #42.

Changes

  • src/ocpp/anonymize.ziganonymizeToJson(value) / anonymizeJsonText(text)
    walk the parsed JSON and emit pretty (2-space) JSON, mirroring the toolkit's
    cli/commands/anonymize.ts:
    • Sensitive keysidTag / identifier"anonymized";
      chargePointSerialNumber / chargeBoxSerialNumber / stationId
      "station-anon"; numeric transactionId → resequenced.
    • PII in strings — email → [redacted-email], phone → [redacted-phone],
      IPv4 → [redacted-ip]. Zig std has no regex, so each is a hand-rolled matcher
      run in three sequential left-to-right passes (JS global-replace semantics).
  • Wired into ocpp.zig; CURRENT_STATE updated.

Mirroring the code, flagging the quirks

Two toolkit behaviors are reproduced deliberately and documented in-code, not
silently "fixed":

  • Meter values are not transformed (the toolkit docstring claims they are).
  • transactionId resequences per occurrence — repeated occurrences of the
    same id get different numbers, so correlation isn't preserved (matches
    txCounter.next++). A stable distinct-id mapping is a possible future
    enhancement.

Safety

Tests

104/104 headless tests pass (native test -Dplatform=null); native check --strict clean; zig fmt clean. New coverage: sensitive-key replacement,
email/phone/IPv4 redaction, numeric meter-value preservation, per-occurrence
transactionId resequencing, JSON round-trip through nested arrays/objects with
escaping, and precise phone/IPv4 matcher boundaries.

Add src/ocpp/anonymize.zig: rewrite a parsed trace to shareable pretty JSON,
mirroring the toolkit's cli/commands/anonymize.ts. Replace known sensitive keys
(idTag / chargePointSerialNumber / chargeBoxSerialNumber / stationId /
identifier), resequence transactionIds, and redact email / phone / IPv4 patterns
in string values. Zig std has no regex, so each pattern is a hand-rolled matcher
applied in three sequential left-to-right passes, matching the toolkit's regex
replacements.

Faithfully mirror two toolkit quirks, flagged in-code rather than silently
diverging: meter values are not transformed (the docstring claims otherwise), and
transactionId resequences per occurrence (repeated ids get different numbers).
Bound recursion depth for untrusted input; pure and headless (no file I/O).

Closes #42.
@sepehr-safari
sepehr-safari merged commit 444b748 into main Jul 11, 2026
3 checks passed
@sepehr-safari
sepehr-safari deleted the feat/anonymize branch July 11, 2026 20:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(engine): anonymize-on-export

1 participant